package copy.scan;

import copy.application.Application;
import copy.application.Process;
import copy.mark.EasyCopy;

import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 作用: 扫描
 *      1. 扫描注解EasyCopy
 *      2. 扫描类型转换器TypeTransform
 */
public class ScanStrategy implements Process {

    private static RoundEnvironment roundEnv ;


    private static ScanStrategy scanSingleBean ;


    public static void initSingleBean(RoundEnvironment r){
        roundEnv = r;
    }
    public static ScanStrategy getScanSingleBean()  {
        if (scanSingleBean == null){
            scanSingleBean = new ScanStrategy();
        }
        return scanSingleBean;
    }


    private ScanStrategy() {

    }



    //转换器全限定类名
    private static final String TRANSFORM_NAME = "copy.mark.trans.TypeTransform";

    private static final Application application = Application.getScanSingleBean();

    //全限限定类名,TypeEmelment
    public static Map<String, TypeElement> easycopyMap = new HashMap<>();
    //全限定类名,TypeElement
    public static Map<String,TypeElement> typetransformMap = new HashMap<>();


    /**
     * 1. 将所有EasyCopy修饰的类的全限定类名
     *    加载到Application容器中的classNameList中.
     *    key:全限定类名 value:TypeElement类节点
     * 2.初始化Application的各个部分组件
     *      元数据解析组件: ParseEasycopyMedaStrategyHandler
     * 3. 开始解析元数据: ParseEasycopyMedaStrategyHandler
     *      a. 方法上的ParaMaps注解元数据,存储到MethodMeda中.再存储到
     *      b. 两个属性的映射元数据信息,保存到PropertyMeda中.再存储到methodMeda
     *
     * @param
     */
    private void doScanEasyCopy( ) throws ClassNotFoundException {
        Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(EasyCopy.class);
        //将全限定类名,保存到Application上下文容器的中
        for (Element e : elements) {
            //1. 将所有EasyCopy修饰的类的全限定类名
            TypeElement typeElement = (TypeElement) e;//强行转成一个类节点
            easycopyMap.put( typeElement.getQualifiedName().toString() , typeElement);
            System.out.println("查找到类名"+typeElement.getQualifiedName().toString());
        }
    }

    /**
     * 扫描类型转换器
     *
     */
    private void doScanTypetransform(){
        //寻找转换器
        Set<? extends Element> allElements = roundEnv.getRootElements();
        for (Element e : allElements) {
            //如果是一个类
            if (e.getKind().isClass()) {
                //遍历所有接口
                TypeElement typeElement = (TypeElement) e;//强行转成一个类节点
                TypeMirror typeMirror = null;
                if ( typeElement.getInterfaces().size() > 0 ){
                    typeMirror = typeElement.getInterfaces().get(0);
                    //获取接口
                    for (TypeMirror mirror : typeElement.getInterfaces()) {
                        //如果实现注解处理器接口
                        String transClass = mirror.toString();
                        transClass = transClass.substring(0,transClass.indexOf("<"));
                        if (transClass.equals(TRANSFORM_NAME)) {
                            //添加转换器
                            System.out.println( "找到转换器: " + typeElement.toString() );
                            typetransformMap.put(typeElement.toString(),typeElement);
                        }
                    }
                }
            }
        }
        //方法体
    }

    @Override
    public void process() throws ClassNotFoundException {
        //启动EasyCopy扫描
        doScanEasyCopy();
        //启动TypeTransform扫描
        doScanTypetransform();
    }
}
